package com.tanklab.signature.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanklab.signature.common.util.HashUtil;
import com.tanklab.signature.common.util.ResultCode;
import com.tanklab.signature.common.util.TimeUtils;
import com.tanklab.signature.ds.req.AddFileReq;
import com.tanklab.signature.ds.resp.CommonResp;
import com.tanklab.signature.entity.Approvallogs;
import com.tanklab.signature.entity.File;
import com.tanklab.signature.entity.Request;
import com.tanklab.signature.entity.User;
import com.tanklab.signature.eth.ChainConnection;
import com.tanklab.signature.mapper.ApprovallogsMapper;
import com.tanklab.signature.mapper.FileMapper;
import com.tanklab.signature.mapper.RequestMapper;
import com.tanklab.signature.mapper.UserMapper;
import com.tanklab.signature.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.lang.Thread.sleep;

@Service
public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements FileService {
    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private RequestMapper requestMapper;

    @Autowired
    private ApprovallogsMapper approvallogsMapper;

    @Autowired
    private UserMapper userMapper;

    @Value("${server.base-url}")
    private String baseUrl;
    @Value("${file.upload-dir}")
    private String fileUploadDir;

//    @Override
//    public CommonResp addFile(AddFileReq addFileReq){
//        CommonResp addfileresp = new CommonResp();
//        // 将填入的信息添加到新的File对象中
//        File file = new File()
//                .setName_file(addFileReq.getFileName())
//                .setFile_path(addFileReq.getFileStorageAddress())
//                .setCreated_time(TimeUtils.getCurrentTime())
//                .setStudent_id(addFileReq.getStudent_id());//还需包括文件所属学生id
//        // 查询自增id下一个是多少
//        QueryWrapper<File> wrapper = new QueryWrapper<>();
//        wrapper.select("id_file");
//        List<File> files = fileMapper.selectList(wrapper);
//        Long maxId = Long.valueOf(0);
//        for (int i = 0; i < files.size();i++){
//            Long perId = files.get(i).getId_file();
//            if (perId > maxId) maxId = perId;
//        }
//        maxId = maxId + 1;
//
//        // 构造json
//        JSONObject fileInfo = new JSONObject();
//        fileInfo.put("fileId",maxId);
//        fileInfo.put("fileName",file.getName_file());
//        fileInfo.put("filePath",file.getFile_path());
//        fileInfo.put("createTime",file.getCreated_time());
//        fileInfo.put("student_id",file.getStudent_id());
//        fileInfo.put("fromRequest",file.getId_fromrequest());
//        // 计算文件的唯一key hash
//        String newfilekey = HashUtil.hash_func(fileInfo.toString(),"MD5");
//        System.out.println("[New File Key] "+newfilekey);
//
//        String txId=null;
//        try{
//            txId= ChainConnection.sendHashToChain(newfilekey);
//        }catch (ChainConnection.BlockchainException e) {
//            System.err.println("上链失败: " + e.getMessage());
//            e.printStackTrace();
//        }
//        if(txId==null){
//            addfileresp.setRet(ResultCode.ERROR);
//            addfileresp.setData("cannot connect to chain");
//            return addfileresp;
//        }
////        txId= "114514";
//        file.setFile_key(newfilekey);
//        file.setTx_id(txId);
//
//        try {
//            sleep(1000);
//        }catch(Exception e){}
//        System.out.println("[New Transaction Id] "+txId);
//
//        // 更新数据库
//        int insert = this.fileMapper.insert(file);
////        System.out.println(maxId);
//        // 返回表单
//        addfileresp.setRet(ResultCode.SUCCESS);
//        addfileresp.setData("Add successfully! Transaction Id: "+txId);
//        return addfileresp;
//
//    }

//    @Override
//    public CommonResp queryOneFile(Long fileId){
//        CommonResp queryonefileresp = new CommonResp();
//        File  file = fileMapper.selectById(fileId);
//
//        if (file == null){
//            queryonefileresp.setRet(ResultCode.NOT_MATCH_ERROR);
//            return queryonefileresp;
//        }
//
//        JSONObject fileInfo = new JSONObject();
//        fileInfo.put("fileId",file.getId_file());
//        fileInfo.put("fileName",file.getName_file());
//        fileInfo.put("filePath",file.getFile_path());
//        fileInfo.put("createTime",file.getCreated_time());
//        fileInfo.put("fileKey",file.getFile_key());
//        fileInfo.put("txId",file.getTx_id());
//        fileInfo.put("fromRequest",file.getId_fromrequest());
//        fileInfo.put("student_id",file.getStudent_id());
//
//        queryonefileresp.setRet(ResultCode.SUCCESS);
//        queryonefileresp.setData(fileInfo);
//        return queryonefileresp;
//    }
//
//    @Override
//    public CommonResp queryAllFile()
//    {
//        CommonResp queryfilesresp = new CommonResp();
//        QueryWrapper<File> wrapper = new QueryWrapper<>();
//        wrapper.select("id_file","id_fromrequest","name_file","file_path","created_time","file_key","student_id","tx_id");
//        List<File> files = fileMapper.selectList(wrapper);
//
//        JSONObject fileinfo = new JSONObject();
//        JSONArray filearr = new JSONArray();
//        for (int i=0;i<files.size();i++){
//            JSONObject peroxinfo = new JSONObject();
//            peroxinfo.put("fileId",files.get(i).getId_file());
//            peroxinfo.put("fileKey",files.get(i).getFile_key());
//            peroxinfo.put("filePath",files.get(i).getFile_path());
//            peroxinfo.put("fileName",files.get(i).getName_file());
//            peroxinfo.put("createTime",files.get(i).getCreated_time());
//            peroxinfo.put("fromRequest",files.get(i).getId_fromrequest());
//            peroxinfo.put("student_id",files.get(i).getStudent_id());
//            peroxinfo.put("txId",files.get(i).getTx_id());
//
//            filearr.add(peroxinfo);
//        }
//        fileinfo.put("fileInfo", filearr);
//        queryfilesresp.setRet(ResultCode.SUCCESS);
//        queryfilesresp.setData(fileinfo);
//        return queryfilesresp;
//    }

//    @Override
//    public CommonResp queryFileByStudentId(Long studentId)
//    {
//        CommonResp queryfilesresp = new CommonResp();
//        QueryWrapper<File> wrapper = new QueryWrapper<>();
//        wrapper.select("id_file","id_fromrequest","name_file","file_path","created_time","file_key","student_id","tx_id");
//        List<File> files = fileMapper.selectList(wrapper);
//
//        JSONObject fileinfo = new JSONObject();
//        JSONArray filearr = new JSONArray();
//        for (int i=0;i<files.size();i++){
//            if(files.get(i).getId_file() == studentId){
//                JSONObject peroxinfo = new JSONObject();
//                peroxinfo.put("fileId",files.get(i).getId_file());
//                peroxinfo.put("fileKey",files.get(i).getFile_key());
//                peroxinfo.put("filePath",files.get(i).getFile_path());
//                peroxinfo.put("fileName",files.get(i).getName_file());
//                peroxinfo.put("createTime",files.get(i).getCreated_time());
//                peroxinfo.put("fromRequest",files.get(i).getId_fromrequest());
//                peroxinfo.put("student_id",files.get(i).getStudent_id());
//                peroxinfo.put("txId",files.get(i).getTx_id());
//                filearr.add(peroxinfo);
//            }
//
//        }
//        fileinfo.put("fileInfo", filearr);
//        queryfilesresp.setRet(ResultCode.SUCCESS);
//        queryfilesresp.setData(fileinfo);
//        return queryfilesresp;
//    }

@Override
public CommonResp getFileDetail(Long fileId) {
    CommonResp resp = new CommonResp();

    // 查询文件基本信息
    File file = fileMapper.selectById(fileId);

    if (file == null) {
        resp.setRet(ResultCode.NOT_MATCH_ERROR);
        resp.setMsg("文件不存在");
        return resp;
    }

    // 构造返回数据
    JSONObject data = new JSONObject();
    data.put("fileId", file.getIdFile());
    data.put("fileName", file.getNameFile());
    data.put("fileType", file.getFileType());
    data.put("fileDescription", file.getFileDescription());
    data.put("fileHash", file.getFileContentHash());
    data.put("createTime", file.getCreatedTime());
//    data.put("filePath", baseUrl + file.getFilePath());

    // 获取上传者信息
    if (file.getUploaderOpenid() != null) {
        QueryWrapper<User> uploaderQuery = new QueryWrapper<>();
        uploaderQuery.eq("openid", file.getUploaderOpenid());
        User uploader = userMapper.selectOne(uploaderQuery);

        if (uploader != null) {
            data.put("initiator", uploader.getUser_name());
            data.put("initiatorIdentity", uploader.getAuthority() == 0 ? "申请者" : "审批者");
        }
    }

    // 查询关联的申请和审批信息
    Long requestId = file.getRequestId();
    if (requestId != null && requestId > 0) {
        // 查询关联的申请信息
        Request request = requestMapper.selectById(requestId);
        if (request != null) {
            data.put("status", request.getStatus()); // 从Request获取状态
            data.put("requestCreatedTime", request.getCreatedTime());
            data.put("requestComments", request.getComments());
            data.put("requestId", request.getIdRequest());

            // 若已审批，查询审批记录
            if ("approve".equals(request.getStatus()) || "reject".equals(request.getStatus())) {
                QueryWrapper<Approvallogs> logsWrapper = new QueryWrapper<>();
                logsWrapper.eq("id_request", requestId);
                Approvallogs log = approvallogsMapper.selectOne(logsWrapper);

                if (log != null) {
                    data.put("approvalTime", log.getActionTime());
                    data.put("approvalAction", log.getAction());
                    data.put("approvalComments", log.getComments());

                    // 获取审批者信息
                    if (log.getApproverOpenid() != null) {
                        QueryWrapper<User> approverQuery = new QueryWrapper<>();
                        approverQuery.eq("openid", log.getApproverOpenid());
                        User approver = userMapper.selectOne(approverQuery);

                        if (approver != null) {
                            data.put("approver", approver.getUser_name());
                            data.put("approverIdentity", approver.getAuthority() >= 100 ? "审批者" : "申请者");
                        }
                    }
                }
            }
        }
    } else {
        // 文件没有关联申请，这在自动创建申请的逻辑下应该不存在
        // 但为了兼容旧数据，仍然添加状态
        data.put("status", "未提交");
    }

    resp.setRet(ResultCode.SUCCESS);
    resp.setMsg("获取文件详情成功");
    resp.setData(data);

    return resp;
}
    @Override
    public CommonResp queryAllFiles() {
        CommonResp resp = new CommonResp();

        QueryWrapper<File> wrapper = new QueryWrapper<>();
        List<File> files = fileMapper.selectList(wrapper);

        List<Map<String, Object>> fileList = new ArrayList<>();

        for (File file : files) {
            JSONObject fileData = new JSONObject();
            fileData.put("fileId", file.getIdFile());
            fileData.put("fileName", file.getNameFile());
            fileData.put("fileType", file.getFileType());
            fileData.put("fileDescription", file.getFileDescription());
            fileData.put("createTime", file.getCreatedTime());
            fileData.put("filePath", baseUrl + file.getFilePath());
            fileData.put("fileContentHash", file.getFileContentHash());
            fileData.put("contentTxId", file.getContentTxId());

            // 获取上传者信息
            if (file.getUploaderOpenid() != null) {
                QueryWrapper<User> uploaderQuery = new QueryWrapper<>();
                uploaderQuery.eq("openid", file.getUploaderOpenid());
                User uploader = userMapper.selectOne(uploaderQuery);

                if (uploader != null) {
                    fileData.put("uploaderName", uploader.getUser_name());
                    fileData.put("uploaderIdentity", uploader.getAuthority() == 0 ? "申请者" : "审批者");
                }
                fileData.put("uploaderOpenid", file.getUploaderOpenid());
            }

            // 获取申请状态
            Long requestId = file.getRequestId();
            if (requestId != null && requestId > 0) {
                Request request = requestMapper.selectById(requestId);
                if (request != null) {
                    fileData.put("status", request.getStatus());
                    fileData.put("requestId", request.getIdRequest());

                    // 若已审批，添加审批信息
                    if ("approve".equals(request.getStatus()) || "reject".equals(request.getStatus())) {
                        QueryWrapper<Approvallogs> logsQuery = new QueryWrapper<>();
                        logsQuery.eq("id_request", requestId);
                        Approvallogs log = approvallogsMapper.selectOne(logsQuery);

                        if (log != null && log.getApproverOpenid() != null) {
                            QueryWrapper<User> approverQuery = new QueryWrapper<>();
                            approverQuery.eq("openid", log.getApproverOpenid());
                            User approver = userMapper.selectOne(approverQuery);

                            if (approver != null) {
                                fileData.put("approverName", approver.getUser_name());
                            }
                            fileData.put("approverOpenid", log.getApproverOpenid());
                            fileData.put("approvalAction", log.getAction());
                            fileData.put("approvalTime", log.getActionTime());
                            fileData.put("approvalComments", log.getComments());
                        }
                    }
                }
            } else {
                fileData.put("status", "未提交");
            }

            fileList.add(fileData);
        }

        JSONObject data = new JSONObject();
        data.put("files", fileList);
        data.put("totalCount", fileList.size());

        resp.setRet(ResultCode.SUCCESS);
        resp.setMsg("查询文件列表成功");
        resp.setData(data);

        return resp;
    }

    /**
     * 根据上传者openId查询文件列表
     */
    @Override
    public CommonResp queryFilesByUploader(String uploaderOpenid) {
        CommonResp resp = new CommonResp();

        if (uploaderOpenid == null || uploaderOpenid.trim().isEmpty()) {
            resp.setRet(ResultCode.PARAM_ERROR);
            resp.setMsg("上传者openId不能为空");
            return resp;
        }

        // 获取用户信息
        QueryWrapper<User> userQuery = new QueryWrapper<>();
        userQuery.eq("openid", uploaderOpenid);
        User uploader = userMapper.selectOne(userQuery);

        if (uploader == null) {
            resp.setRet(ResultCode.USER_NOT_EXIST);
            resp.setMsg("用户不存在");
            return resp;
        }

        // 查询该用户上传的文件
        QueryWrapper<File> wrapper = new QueryWrapper<>();
        wrapper.eq("uploader_openid", uploaderOpenid);
        List<File> files = fileMapper.selectList(wrapper);

        List<Map<String, Object>> fileList = new ArrayList<>();

        for (File file : files) {
            JSONObject fileData = new JSONObject();
            fileData.put("fileId", file.getIdFile());
            fileData.put("fileName", file.getNameFile());
            fileData.put("fileType", file.getFileType());
            fileData.put("fileDescription", file.getFileDescription());
            fileData.put("createTime", file.getCreatedTime());
            fileData.put("filePath", baseUrl + file.getFilePath());
            fileData.put("fileContentHash", file.getFileContentHash());
            fileData.put("contentTxId", file.getContentTxId());

            // 添加上传者信息
            fileData.put("uploaderName", uploader.getUser_name());
            fileData.put("uploaderIdentity", uploader.getAuthority() == 0 ? "申请者" : "审批者");

            // 获取申请状态
            Long requestId = file.getRequestId();
            if (requestId != null && requestId > 0) {
                Request request = requestMapper.selectById(requestId);
                if (request != null) {
                    fileData.put("status", request.getStatus());
                    fileData.put("requestId", request.getIdRequest());

                    // 若已审批，添加审批信息
                    if ("approve".equals(request.getStatus()) || "reject".equals(request.getStatus())) {
                        QueryWrapper<Approvallogs> logsQuery = new QueryWrapper<>();
                        logsQuery.eq("id_request", requestId);
                        Approvallogs log = approvallogsMapper.selectOne(logsQuery);

                        if (log != null && log.getApproverOpenid() != null) {
                            QueryWrapper<User> approverQuery = new QueryWrapper<>();
                            approverQuery.eq("openid", log.getApproverOpenid());
                            User approver = userMapper.selectOne(approverQuery);

                            if (approver != null) {
                                fileData.put("approverName", approver.getUser_name());
                            }
                            fileData.put("approverOpenid", log.getApproverOpenid());
                            fileData.put("approvalAction", log.getAction());
                            fileData.put("approvalTime", log.getActionTime());
                            fileData.put("approvalComments", log.getComments());
                        }
                    }
                }
            } else {
                fileData.put("status", "未提交");
            }

            fileList.add(fileData);
        }

        Map<String, Object> data = new HashMap<>();
        data.put("files", fileList);
        data.put("totalCount", fileList.size());
        data.put("uploaderName", uploader.getUser_name());

        resp.setRet(ResultCode.SUCCESS);
        resp.setMsg("查询用户文件列表成功");
        resp.setData(data);

        return resp;
    }

    // Deprecated
    @Override
    @Transactional
    public CommonResp deleteFile(Long fileId, String openid) {
        CommonResp resp = new CommonResp();

        // 1. 查询文件是否存在
        File file = fileMapper.selectById(fileId);
        if (file == null) {
            resp.setRet(ResultCode.NOT_MATCH_ERROR);
            resp.setMsg("文件不存在");
            return resp;
        }

        // 2. 权限校验：检查当前用户是否为文件上传者
        if (!openid.equals(file.getUploaderOpenid())) {
            resp.setRet(ResultCode.PERMISSION_DENIED);
            resp.setMsg("无权删除他人上传的文件");
            return resp;
        }

        // 3. 查询是否有关联的申请
        Long requestId = file.getRequestId();
        if (requestId != null) {
            // 查询申请状态
            Request request = requestMapper.selectById(requestId);
            if (request != null) {
                // 如果申请已经被审批通过，不允许删除
                if ("approve".equals(request.getStatus())) {
                    resp.setRet(ResultCode.PERMISSION_DENIED);
                    resp.setMsg("已审批通过的文件不能删除");
                    return resp;
                }

                // 删除关联的审批记录
                QueryWrapper<Approvallogs> logsQuery = new QueryWrapper<>();
                logsQuery.eq("id_request", requestId);
                approvallogsMapper.delete(logsQuery);

                // 删除申请记录
                requestMapper.deleteById(requestId);
            }
        }

        // 4. 获取文件路径准备删除物理文件
        String filePath = file.getFilePath();
        if (filePath != null && !filePath.isEmpty()) {
            try {
                // 从文件路径中截取文件名
                String fileName = filePath.substring(filePath.lastIndexOf("/") + 1);
                Path uploadPath = Paths.get(fileUploadDir);
                Path fullPath = uploadPath.resolve(fileName);

                // 删除物理文件
                Files.deleteIfExists(fullPath);
            } catch (Exception e) {
                // 记录错误但不影响数据库删除操作
                System.err.println("删除物理文件失败: " + e.getMessage());
            }
        }

        // 5. 删除数据库中的文件记录
        int result = fileMapper.deleteById(fileId);

        if (result > 0) {
            resp.setRet(ResultCode.SUCCESS);
            resp.setMsg("文件删除成功");
        } else {
            resp.setRet(ResultCode.ERROR);
            resp.setMsg("文件删除失败");
        }

        return resp;
    }
}
